/**
 * Author(s): xuming.Wong <xuming.Wong@gmail.com>
 */

#include "WdlFile.h"

namespace PQGameCore
{
	WdlFile::~WdlFile(void)
	{
	}

	WdlFile::WdlFile()
	{
		version=0;//not init
		mini_map=0;
	}

	void WdlFile::init(PQEngine::FileBase *f)
	{
		if(f==0){
			return;
		}
		mpq_file=f;

		int size=0;
		char name[5];
		f->open();
		while (!f->eof()) {
			f->read(name,4);
			f->read(&size, 4);
			flipcc(name);
			name[4] = 0;

			if (strncmp(name, "MVER", 4) == 0) {
				if(size!=0){
					f->read(&version, 4);
				}

			} else if (strncmp(name, "MWMO", 4) == 0) {
				if(size!=0){

				}
				f->advance(size);
			} else if (strncmp(name, "MWID", 4) == 0) {
				if(size!=0){

				}
				f->advance(size);
			} else if (strncmp(name, "MODF", 4) == 0) {
				if(size!=0){

				}
				f->advance(size);
			} else if (strncmp(name, "MAOF", 4) == 0) {
				if(size!=0){
					/*
					Contains 64*64 = 4096 unsigned 32-bit integers, 
					these are absolute offsets in the file to each map tile's MapAreaLow-array-entry. 
					For unused tiles the value is 0.
					*/
					f->read(maofbuf,64*64*4);
					
					for (int j=0; j<64; j++) {
						for (int i=0; i<64; i++) {
							if (maofbuf[j][i]) {
								tilebufs[j][i]=new short[17*17];
								tilebufs2[j][i]=new short[16*16];
								f->seek(maofbuf[j][i]+8);
								f->read(tilebufs[j][i],17*17*2);
								f->read(tilebufs2[j][i],16*16*2);
							}
						}
					}
					f->close();
					break;
				}
				f->advance(size);
			} else if (strncmp(name, "MARE", 4) == 0) {
				/*
				Heightmap for one map tile. 
				Contains 17*17 + 16*16 = 545 signed 16-bit integers. 
				So a 17 by 17 grid of height values is given, with additional height values in between grid points. 
				Here, the "outer" 17x17 points are listed (in the usual row major order), 
				followed by 16x16 "inner" points. 
				The height values are on the same scale as those used in the regular height maps.
				*/

				f->advance(size);
			} 
			else if (strncmp(name, "MAHO", 4) == 0) {
				/*
				After each MARE chunk there follows a MAHO (MapAreaHOles) chunk.
				It may be left out if the data is supposed to be 0 all the time.
				Its an array of 16 shorts. Each short is a bitmask.
				If the bit is not set, there is a hole at this position.
				*/
				f->advance(size);
			}else{
				f->advance(size);
			}

		}


		initMiniMap();
	}

	void WdlFile::initMiniMap()
	{
		//In MARE
		PQEngine::FileBase* f=mpq_file;
		if(f==0){
			return;
		}
		mini_map = new unsigned int[512*512];
		memset(mini_map,255,512*512*4);
		
		for (int j=0; j<64; j++) {
			for (int i=0; i<64; i++) {
				if (maofbuf[j][i]) {
					short *tilebuf=tilebufs[j][i];
					// make minimap
					// for a 512x512 minimap texture, and 64x64 tiles, one tile is 8x8 pixels
					for (int z=0; z<8; z++) {
						for (int x=0; x<8; x++) {
							short hval = tilebuf[(z*2)*17+x*2];
							// make rgb from height value
							unsigned char r,g,b;
							if (hval < 0) {
								// water = blue
								if (hval < -511) hval = -511;
								hval /= -2;
								r = g = 0;
								b = 255 - hval;
							} else {
								unsigned char r1,r2,g1,g2,b1,b2;
								float t;
								if (hval < 600) {
									r1 = 20;
									r2 = 137;
									g1 = 149;
									g2 = 84;
									b1 = 7;
									b2 = 21;
									t = hval / 600.0f;
								}else if (hval < 1200) {
									r2 = 96;
									r1 = 137;
									g2 = 96;
									g1 = 84;
									b2 = 96;
									b1 = 21;
									t = (hval-600) / 600.0f;
								}else{
									r1 = 96;
									r2 = 255;
									g1 = 96;
									g2 = 255;
									b1 = 96;
									b2 = 255;
									if (hval >= 1600) hval = 1599;
									t = (hval-1200) / 600.0f;
								}
								r = (unsigned char)(r2*t + r1*(1.0f-t));
								g = (unsigned char)(g2*t + g1*(1.0f-t));
								b = (unsigned char)(b2*t + b1*(1.0f-t));
							}

							mini_map[(j*8+z)*512 + i*8+x] = (r) | (g<<8) | (b<<16) | (255 << 24);
						}
					}
				}
			}
		}
	}
}
